/**
 * 
 */
package org.dragonfire.dasm.directives;

import java.util.ArrayList;

import org.dragonfire.dasm.Command;
import org.dragonfire.dasm.Listing;
import org.dragonfire.dasm.DirectiveManager.Directive;
import org.dragonfire.dasm.instr.InstructionTable;

/**
 * Adds an instruction to the {@link InstructionTable} which can be used on all
 * subsequent lines.<br />
 * <br />
 * Format:<br />
 * <code>#INSTRUCTION <i>&lt;name&gt;</i>,<i>&lt;size&gt;</i>,<i>&lt;code&gt;</i>[,<i>&lt;param1&gt;</i>[,<i>&lt;param2&gt;</i>[,...]]]</code><br />
 * <br />
 * Parameters:<br />
 * <table>
 * <tr>
 * <td><code>name</code></td>
 * <td>(String) The mnemonic, or name of this instruction</td>
 * </tr>
 * <tr>
 * <td><code>size</code></td>
 * <td>(Integer) The size, in bytes, of the compiled instruction</td>
 * </tr>
 * <tr>
 * <td><code>code</code></td>
 * <td>(String) A binary representation of the instruction's opcode, with
 * markers for the locations of parameters. See
 * {@link org.dragonfire.dasm.instr.Instruction} for details on the syntax</td>
 * </tr>
 * <tr>
 * <td><code>param1</code></td>
 * <td>(String) A parameter definition that describes what parameter types are
 * accepted by this parameter. See {@link org.dragonfire.dasm.instr.CommandDef}
 * for a list of parameter formats and details about each</td>
 * </tr>
 * </table><br />
 * Errors:<br />
 * <table>
 * <tr>
 * <td><code>ERROR_NOT_ENOUGH_ARGS</code></td>
 * <td>Thrown if <code>name</code>, <code>size</code>, or
 * <code>code</code> is undefined</td>
 * </tr>
 * <tr>
 * <td><code>ERROR_STRING_REQUIRED</code></td>
 * <td>Thrown if <code>code</code>, <code>param1</code>, or
 * <code>name</code> is not a string</td>
 * </tr>
 * <tr>
 * <td><code>ERROR_INT_REQUIRED</code></td>
 * <td>Thrown if <code>size</code> is not an integer</td>
 * </tr>
 * </table>
 * 
 * @see org.dragonfire.dasm.instr.Instruction
 * @see org.dragonfire.dasm.instr.InstructionTable
 * @author Darth Android
 * @version 2.0
 */
public class Instruction extends Directive {

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ArrayList<Listing> pass1(Command c) {
		// get args
		String name = evalString(c.getParam(0));
		int size = evalInt(c.getParam(1));
		String code = evalString(c.getParam(2));
		// get instruction parameters
		String[] args = new String[c.getParams().length - 3];
		for (int i = 0; i < args.length; i++) {
			args[i] = evalString(c.getParam(i + 3));
		}
		org.dragonfire.dasm.instr.Instruction ins = new org.dragonfire.dasm.instr.Instruction(name, args, code, size);
		// add the instruction
		getCompiler().getInstructions().addCommand(ins);
		return null;
	}
}
